package vfs.client.rmi;

import vfs.common.User;
import vfs.common.rmi.AbstractRmiManager;
import vfs.common.rmi.RmiDispatcher;

import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

/**
 * Singleton holding RMI operations
 * <p/>
 * User: serge
 * Date: 21.11.13
 * Time: 22:02
 */
public class ClientRmiManager extends AbstractRmiManager
{
    private static final ClientRmiManager ourInstance = new ClientRmiManager();
    private RmiDispatcher rmiDispatcher;
    private boolean sessionStarted = false;
    private User user;

    private ClientRmiManager()
    {
    }

    public boolean isSessionStarted()
    {
        return sessionStarted;
    }

    public static ClientRmiManager getInstance()
    {
        return ourInstance;
    }

    public User getUser()
    {
        return user;
    }

    public RmiDispatcher getRmiDispatcher()
    {
        return rmiDispatcher;
    }

    /**
     * though RMI doesn't maintain sessions, here session is considered by interval between user is registered on
     * server and unregistered by unavailability or session close.
     *
     * @param hostname
     * @param port set to 0 to use default
     * @param userName
     * @throws RemoteException
     * @throws AlreadyBoundException
     * @throws NotBoundException
     */
    public void startSession(String hostname, int port, String userName) throws RemoteException, AlreadyBoundException,
            NotBoundException
    {
        user = new User(userName, new ClientRmiBroadcastListener());

        registry = port == 0 ? LocateRegistry.getRegistry(hostname) : LocateRegistry.getRegistry(hostname, port);
        rmiDispatcher = (RmiDispatcher) registry.lookup(bindName);

        sessionStarted = rmiDispatcher.registerUser(user);
    }

    public boolean closeSession() throws RemoteException
    {
        boolean closed = rmiDispatcher.unregisterUser(user);

        if (closed)
        {
            registry = null;
            user = null;
            sessionStarted = false;
        }

        return closed;
    }
}
